\section{The Meta Schema}
\label{sec:The Meta Schema}
{\small
\begin{verbatim}
/* ******************************************************************** */
/*                          SOS meta schema                             */
/* ******************************************************************** */

with agg, dir;

schema mta
{

typedef Mapping <sos_String, sos_Schema_type> sos_Type_table;

class sos_Imports : List <sos_Schema_module> (FALSE)
{
public:
   sos_Schema_type lookup_type (sos_String name,
                                sos_Bool   look_for_alias = FALSE);
};

class sos_Schema_module : sos_Named
{
public:
   static Directory<sos_Schema_module>  schema_dir ();
   static sos_Schema_module             lookup (sos_String);
   static sos_Schema_module             retrieve (sos_Container);

   local  sos_String                    name;
   local  sos_Imports                   imports;
   local  List <sos_Schema_type>        types;
   local  sos_Type_table                type_table;
          sos_Bool                      has_external_import;
          sos_Bool                      has_external_types;
   local  List <sos_Schema_impl>        impls;

   sos_Schema_type  lookup_type (sos_String name,
                                 sos_Bool   look_for_alias = FALSE);
   void             open_imports ();
   void             close_imports ();
   void             install ();
};

class sos_Schema_impl {};

class sos_Method_impl {};

class sos_Expr {};
\end{verbatim}
\pagebreak
\begin{verbatim}
class sos_Int_expr : sos_Expr
{
public:
   sos_Int    value;
};

class sos_Identifier : sos_Expr
{
public:
   sos_String id;
};

class sos_Type_name
{
public:
   sos_Schema_type      make_root_type ();
   sos_Schema_type      make_base_type ();
   List <sos_Expr>      create_params ();

   abstract sos_Schema_type     make_type ();
   abstract sos_String          make_type_name ();
};

class sos_Schema_type : sos_Type, sos_Type_name
{
public:
   sos_Bool     is_derived_from (sos_Type);      // -> sos_Type
   sos_Bool     is_derived_from_some (sos_Type); // -> sos_Type
   sos_Bool     is_scalar ();                    // -> sos_Type
   sos_Type     base ();                         // -> sos_Type

   sos_Schema_type      make_type ();            // -> sos_Type_name
   sos_String           make_type_name ();       // -> sos_Type_name

protected:
   static sos_Bool total_equal (sos_Schema_type,
                                sos_Object, sos_Eq_kind);
   static sos_Int  total_hash_value (sos_Schema_type);
};

class sos_Unidentified_type : sos_Type_name, sos_Named
{
public:
   local sos_String     name;

   sos_Schema_type      make_type ();            // -> sos_Type_name
   sos_String           make_type_name ();       // -> sos_Type_name
};
\end{verbatim}
\pagebreak
\begin{verbatim}
class sos_Type_with_params : sos_Type_name
{
public:
   sos_Type_name        type_name;
   List <sos_Expr>      params;

   List <sos_Expr>      create_params ();        // -> sos_Type_name
   sos_Schema_type      make_type ();            // -> sos_Type_name
   sos_String           make_type_name ();       // -> sos_Type_name
};

class sos_Generic_instantiation : sos_Type_name
{
public:
          sos_Class_type        gen;
   local  List <sos_Type_name>  gen_params;
          sos_Class_type        instantiation;

   sos_Bool             is_universal ();

   sos_Schema_type      make_type ();            // -> sos_Type_name
   sos_String           make_type_name ();       // -> sos_Type_name
};

class sos_Gen_param : sos_Type_name, sos_Named
{
public:
   sos_String     name;
   sos_Type_name  super_class;

   sos_Schema_type      make_type ();            // -> sos_Type_name
   sos_String           make_type_name ();       // -> sos_Type_name
};

class sos_Param : sos_Named
{
public:
   sos_String     name;
   sos_Type_name  type_name;
   sos_Bool       is_ref;
   sos_Expr       default_expr;
};

enum sos_Method_kind
{
   sos_PRIVATE,
   sos_PROTECTED,
   sos_PUBLIC
};
\end{verbatim}
\pagebreak
\begin{verbatim}
class sos_Method : sos_Named
{
public:
         sos_String             name;
         sos_Method_kind        kind;
         sos_Bool               is_static;
         sos_Bool               is_abstract;
         sos_Bool               is_operator;
         sos_Bool               is_predefined;
         sos_Method             generated_from;
   local sos_Class_type         defined_in;
         List <sos_Param>       params;
         sos_Type_name          result_type;
   local List <sos_Method_impl> impls;

   sos_Bool     overloads (sos_Method);
   sos_Bool     redefines (sos_Method);
   sos_Object   execute (sos_Object, Array <sos_Object>);
};

class sos_Method_table
      : Mapping <sos_String, List <sos_Method>> (FALSE, TRUE, FALSE)
{
public:
   sos_Method           lookup (sos_Method);
   sos_Method           lookup_or_add (sos_Method);
   sos_Method           replace_or_add (sos_Method);

   sos_Comp_method      lookup_comp (sos_String, sos_Bool is_set);
};

class sos_Comp_method : sos_Method
{
public:
   sos_Expr       init_expr;
   sos_Bool       is_set;
   sos_Bool       is_value;
   sos_Bool       is_local;
   sos_Int        offset;
};

class sos_Union_type : sos_Schema_type 
{
public:
   local  List <sos_Type_name> uniteds;

protected:
   static sos_Bool local_equal (sos_Union_type,
                                sos_Object, sos_Eq_kind);
   static sos_Int  local_hash_value (sos_Union_type);
};
\end{verbatim}
\pagebreak
\begin{verbatim}
class sos_Typedef_type : sos_Schema_type 
{
public:
   sos_Type_name        type_name;

   sos_Schema_type      make_base_type ();       // -> sos_Type_name

protected:
   static sos_Bool local_equal (sos_Typedef_type,
                                sos_Object, sos_Eq_kind);
   static sos_Int  local_hash_value (sos_Typedef_type);
};

class sos_Enum_type : sos_Schema_type 
{
public:
   local  List <sos_String>     literals;

          sos_Scalar_object     make_object (sos_String);
          sos_String            make_string (sos_Scalar_object);

protected:
   static sos_Bool local_equal (sos_Enum_type,
                                sos_Object, sos_Eq_kind);
   static sos_Int  local_hash_value (sos_Enum_type);
};

class sos_Extern_type : sos_Schema_type 
{
};

class sos_Forward_class_type : sos_Schema_type 
{
public:
   sos_Class_type       complete;

   sos_Schema_type      make_base_type ();       // -> sos_Type_name

protected:
   static sos_Bool local_equal (sos_Forward_class_type,
                                sos_Object, sos_Eq_kind);
   static sos_Int  local_hash_value (sos_Forward_class_type);
};

class sos_Super_class
{
public:
   sos_Class_type  super_class;
   List <sos_Expr> create_params;
   sos_Int         offset;
};

class sos_Class_type  : sos_Schema_type 
{
public:
          List <sos_Gen_param>          gen_params;
          List <sos_Param>              create_params;
          sos_Bool                      has_init_comps;
          sos_Bool                      is_abstract;
          List <sos_Type_name>          friends;
          List <sos_Type_name>          super_classes;
   local  List <sos_Super_class>        super_closure;
          List <sos_Method>             methods;
          List <sos_Method>             comp_methods;
          List <sos_Method>             static_methods;
   local  sos_Method_table              inherited_methods;

          sos_Generic_instantiation     generated_from;
   local  sos_String                    root_name;

          sos_Int                       local_size;

   sos_Class_type    root_class ();

   sos_Bool         is_derived_from (sos_Type);      // -> sos_Type
   sos_Bool         is_derived_from_some (sos_Type); // -> sos_Type
   sos_Type         root ();                         // -> sos_Type
   sos_Schema_type  make_root_type ();               // -> sos_Type_name
   sos_String       make_type_name ();               // -> sos_Type_name

protected:
   static sos_Bool local_equal (sos_Class_type,
                                sos_Object, sos_Eq_kind);
   static sos_Int  local_hash_value (sos_Class_type);
};

} // ** schema mta **
\end{verbatim}
}
